{*******************************************************************************
* The contents of this file are used with permission, subject to the Mozilla   *
* Public License Version 1.1 (the "License"); you may not use this file except *
* in compliance with the License. You may obtain a copy of the License at      *
* http://www.mozilla.org/MPL/                                                  *
*                                                                              *
* Software distributed under the License is distributed on an "AS IS" basis,   *
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for *
* the specific language governing rights and limitations under the License.    *
*                                                                              *
* The Original Code is distributed as part of the "mediate" product and is     *
* Copyright (C) @home media limited. All Rights Reserved.                      *
*                                                                              *
* Email: support@athomemedia.co.uk                                             *
* Web:   http://www.athomemedia.co.uk                                          *
*******************************************************************************}

unit InputActionForm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, StdCtrls, ExtCtrls, VellemanManager, VellemanInputs;

type
  TfrmInputActionConfig = class(TForm)
    gbInputProperties: TGroupBox;
    Label1: TLabel;
    edInputName: TEdit;
    btOK: TButton;
    btCancel: TButton;
    gbActionProperties: TGroupBox;
    Label4: TLabel;
    Label5: TLabel;
    gbRepeatProperties: TGroupBox;
    rbRepeatNone: TRadioButton;
    rbRepeatShort: TRadioButton;
    rbRepeatLong: TRadioButton;
    txDelayType: TLabel;
    edRepeatDelay: TEdit;
    udRepeatDelay: TUpDown;
    Label7: TLabel;
    edRepeatInterval: TEdit;
    udRepeatInterval: TUpDown;
    ecShortAction: TComboBox;
    ecLongAction: TComboBox;
    pnAnalogControls: TPanel;
    Label2: TLabel;
    Label3: TLabel;
    edMinValue: TEdit;
    edMaxValue: TEdit;
    udMinValue: TUpDown;
    udMaxValue: TUpDown;
    btTrain: TButton;
    Label8: TLabel;
    txCurrentValue: TLabel;
    tmCurrentValue: TTimer;
    procedure FormShow(Sender: TObject);
    procedure btOKClick(Sender: TObject);
    procedure tmCurrentValueTimer(Sender: TObject);
    procedure btTrainMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure btTrainMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure rbRepeatTypeClick(Sender: TObject);
  private
    { Private declarations }
    FVelleman: TAHMVellemanManager;
    FInput: TAHMVellemanInputAction;
    FTraining: Boolean;
    FTrainedMin: Integer;
    FTrainedMax: Integer;
    function GetCurrentValue: Integer;
    procedure ShowInputSettings;
    procedure ConfigureRepeatControls;
    procedure UpdateInputSettings;
  protected
    { Protected declarations }
    property VellemanInput: TAHMVellemanInputAction read FInput write FInput;
    property VellemanManager: TAHMVellemanManager read FVelleman write FVelleman;
    property CurrentValue: Integer read GetCurrentValue;
  public
    { Public declarations }
    class function Configure(Velleman: TAHMVellemanManager; Input: TAHMVellemanInputAction): Boolean;
  end;


implementation

{$R *.dfm}

class function TfrmInputActionConfig.Configure(Velleman: TAHMVellemanManager; Input: TAHMVellemanInputAction): Boolean;
begin
  with Self.Create(nil) do
  try
    VellemanInput := Input;
    VellemanManager := Velleman;
    Result := (ShowModal = mrOK);
  finally
    Free;
  end;
end;

procedure TfrmInputActionConfig.FormShow(Sender: TObject);
begin
  // Display settings
  ShowInputSettings;
  ConfigureRepeatControls;
end;

procedure TfrmInputActionConfig.tmCurrentValueTimer(Sender: TObject);
var
  SnapshotValue: Integer;
begin
  // Update preview of current analog value
  SnapShotValue := CurrentValue;
  txCurrentValue.Caption := IntToStr(SnapshotValue);

  // Update min/max values during training mode
  if FTraining then
  begin
    if SnapshotValue < FTrainedMin then FTrainedMin := SnapshotValue;
    if SnapshotValue > FTrainedMax then FTrainedMax := SnapshotValue;

    // Perform live update of trained values
    udMinValue.Position := FTrainedMin;
    udMaxValue.Position := FTrainedMax;
  end;
end;

procedure TfrmInputActionConfig.btOKClick(Sender: TObject);
begin
  // Provide a default name if omitted then save changes
  if edInputName.Text = '' then edInputName.Text := 'Unnamed';
  UpdateInputSettings;
end;

procedure TfrmInputActionConfig.btTrainMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  // Enter training mode
  FTrainedMin := CurrentValue;
  FTrainedMax := CurrentValue;
  FTraining := True;
end;

procedure TfrmInputActionConfig.btTrainMouseUp(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  // Complete training mode and finalise learned values
  FTraining := False;
  udMinValue.Position := FTrainedMin;
  udMaxValue.Position := FTrainedMax;
end;

procedure TfrmInputActionConfig.rbRepeatTypeClick(Sender: TObject);
begin
  // Enable repeating action controls according to repeat mode
  ConfigureRepeatControls;
end;

function TfrmInputActionConfig.GetCurrentValue: Integer;
begin
  // Get current analog input value from appropriate channel
  case FInput.InputType of
    inAnalog1: Result := FVelleman.Inputs.CurrentAnalogValue1;
    inAnalog2: Result := FVelleman.Inputs.CurrentAnalogValue2;
    else Result := 0;
  end;
end;

procedure TfrmInputActionConfig.ShowInputSettings;
begin
  if Assigned(FInput) then
  begin
    // Generic settings for analog & digital inputs
    edInputName.Text := FInput.InputName;
    udRepeatDelay.Position := FInput.RepeatDelay;
    udRepeatInterval.Position := FInput.RepeatInterval;
    ecShortAction.Text := FInput.ShortAction;
    ecLongAction.Text := FInput.LongAction;

    // Determine repeat behaviour
    if not FInput.RepeatAction then rbRepeatNone.Checked := True
    else if FInput.LongAction = '' then rbRepeatShort.Checked := True
    else rbRepeatLong.Checked := True;

    if FInput is TAHMVellemanAnalogAction then
    begin
      // Analog specific settings
      udMinValue.Position := TAHMVellemanAnalogAction(FInput).MinValue;
      udMaxValue.Position := TAHMVellemanAnalogAction(FInput).MaxValue;
      tmCurrentValue.Enabled := True;
      Caption := 'Analog input ' + IntToStr(Ord(FInput.InputType)) + ' configuration';
    end
    else
    begin
      // Hide analog control panel & shuffle others up
      pnAnalogControls.Hide;
      gbInputProperties.Height := gbInputProperties.Height - pnAnalogControls.Height;
      gbRepeatProperties.Top := gbRepeatProperties.Top - pnAnalogControls.Height;
      gbActionProperties.Top := gbActionProperties.Top - pnAnalogControls.Height;
      Caption := 'Digital input ' + IntToStr(FInput.Index + 1) + ' configuration';
    end;
  end;
end;

procedure TfrmInputActionConfig.ConfigureRepeatControls;
begin
  // Repeat interval is only relevant if we want repeating actions
  edRepeatInterval.Enabled := not rbRepeatNone.Checked;
  udRepeatInterval.Enabled := not rbRepeatNone.Checked;

  // Long not allowed if we want repeating short actions
  ecLongAction.Enabled := not rbRepeatShort.Checked;
end;

procedure TfrmInputActionConfig.UpdateInputSettings;
begin
  if Assigned(FInput) then
  begin
    // Generic settings for analog & digital inputs
    FInput.InputName := edInputName.Text;
    FInput.RepeatDelay := udRepeatDelay.Position;
    FInput.RepeatInterval := udRepeatInterval.Position;
    FInput.ShortAction := ecShortAction.Text;
    FInput.LongAction := ecLongAction.Text;
    FInput.RepeatAction := not rbRepeatNone.Checked;

    if FInput is TAHMVellemanAnalogAction then
    begin
      // Analog specific settings
      TAHMVellemanAnalogAction(FInput).MinValue := udMinValue.Position;
      TAHMVellemanAnalogAction(FInput).MaxValue := udMaxValue.Position;
    end;
  end;
end;




end.
